-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for connection pool monitoring #702
base: master
Are you sure you want to change the base?
Conversation
These trace events were added.
We can use an extension's Additionally, some events do not support callbacks. These are events that are unrelated to requests.
|
Could you demo some log output as part of the description here? |
script import asyncio
import logging
import httpcore
logging.basicConfig(
format="%(levelname)s [%(asctime)s] %(name)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
logging.getLogger("httpcore.connection_pool").setLevel(logging.DEBUG)
async def main():
async with httpcore.AsyncConnectionPool() as pool:
tasks = []
for i in range(5):
tasks.append(pool.request('GET', 'http://encode.io'))
await asyncio.gather(*tasks)
asyncio.run(main()) OUTPUT DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.started origin='http://encode.io:80'
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.complete return_value=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.started connection=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.complete
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Waiting for a connection.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 1 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Connection received.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 0 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.started origin='http://encode.io:80'
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.complete return_value=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.started connection=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.complete
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Waiting for a connection.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 1 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Connection received.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 0 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.started origin='http://encode.io:80'
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.complete return_value=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.started connection=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.complete
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Waiting for a connection.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 1 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Connection received.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 0 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.started origin='http://encode.io:80'
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.complete return_value=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.started connection=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.complete
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Waiting for a connection.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 1 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Connection received.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 0 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.started origin='http://encode.io:80'
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - create_connection.complete return_value=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.started connection=<AsyncHTTPConnection [CONNECTING]>
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - set_connection.complete
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Waiting for a connection.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 1 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - Connection received.
DEBUG [2023-05-30 16:00:10] httpcore.connection_pool - The ConnectionPool currently has 0 request(s) awaiting connections.
DEBUG [2023-05-30 16:00:11] httpcore.connection_pool - Connection: <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]> was returned into the pool
DEBUG [2023-05-30 16:00:11] httpcore.connection_pool - Connection: <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]> was returned into the pool
DEBUG [2023-05-30 16:00:11] httpcore.connection_pool - Connection: <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]> was returned into the pool
DEBUG [2023-05-30 16:00:11] httpcore.connection_pool - Connection: <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]> was returned into the pool
DEBUG [2023-05-30 16:00:11] httpcore.connection_pool - Connection: <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]> was returned into the pool |
With the trace extention enabled import asyncio
import httpcore
async def log(a, b):
if a.startswith('connection_pool'):
print(a, b)
async def main():
async with httpcore.AsyncConnectionPool(max_connections=1) as pool:
tasks = []
for i in range(5):
tasks.append(pool.request('GET', 'http://encode.io', extensions={'trace': log}))
await asyncio.gather(*tasks)
asyncio.run(main()) OUTPUT connection_pool.set_connection.started {'connection': <AsyncHTTPConnection [CONNECTING]>}
connection_pool.set_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 1]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.unset_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, ACTIVE, Request Count: 2]>}
connection_pool.unset_connection.complete {'return_value': None}
connection_pool.unset_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, ACTIVE, Request Count: 2]>}
connection_pool.unset_connection.complete {'return_value': None}
connection_pool.unset_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, ACTIVE, Request Count: 2]>}
connection_pool.unset_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 2]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 2]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 2]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.unset_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, ACTIVE, Request Count: 3]>}
connection_pool.unset_connection.complete {'return_value': None}
connection_pool.unset_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, ACTIVE, Request Count: 3]>}
connection_pool.unset_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 3]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 3]>}
connection_pool.reuse_connection.complete {'return_value': None}
connection_pool.unset_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, ACTIVE, Request Count: 4]>}
connection_pool.unset_connection.complete {'return_value': None}
connection_pool.reuse_connection.started {'connection': <AsyncHTTPConnection ['http://encode.io:80', HTTP/1.1, IDLE, Request Count: 4]>}
connection_pool.reuse_connection.complete {'return_value': None} |
Wonderful - thanks for working through this. We should avoid adding extra state as part of this change, so I'd suggest we avoid the It seems to me that the bits we'd like to trace don't fit in as well with the Maybe we'd implement that with a The bits we want to monitor are state changes to Suppose we started just with the following trace events/debug lines... DEBUG [2023-06-09 10:55:09] httpcore.connection_pool - add_connection <HTTPConnection [...]>
DEBUG [2023-06-09 10:55:09] httpcore.connection_pool - add_request <Request [...]>
DEBUG [2023-06-09 10:55:09] httpcore.connection_pool - assign_request_to_connection <Request [...]> <HTTPConnection >
DEBUG [2023-06-09 10:55:09] httpcore.connection_pool - unassign_request_from_connection <Request [...]> <HTTPConnection [...]>
DEBUG [2023-06-09 10:55:09] httpcore.connection_pool - timeout_waiting_for_connection <Request [...]>
DEBUG [2023-06-09 10:55:09] httpcore.connection_pool - remove_request <Request [...]>
DEBUG [2023-06-09 10:55:09] httpcore.connection_pool - remove_connection <HTTPConnection [...]> Would that be sufficiently comprehensive? |
6888dbf
to
8fa39ed
Compare
I've added all of the events you mentioned, as well as the "reuse_connection" event. This is how it looks like now
|
Also timeout event
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really promising...
Here's some initial suggestions.
Co-authored-by: Tom Christie <tom@tomchristie.com>
…nto add-pool-monitoring
What's the status of this PR? |
closes #508